#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Introduction to Programming in Java - An Interdisciplinary Approach

All book programs ported to Python by
Scott C. King (revisionx at {gee}ma1l <dot> c0m).

All program examples pass Pylint with a perfect 10.00 score.
Pylint:  http://www.pylint.org/


Program 1.4.4 - Self-avoiding random walks

Syntax:
python selfavoidingrandomwalks.py 20 1000


Notes:
int(sys.argv[1]) == Integer.parseInt(args[0])

sys is a required import here in order to use command line arguments.
https://docs.python.org/2/tutorial/stdlib.html

random is a required import as a substitute for Java's Math.random()
https://docs.python.org/2/library/random.html

'''

import sys
import random


def main():
    ''' Do T random self-avoiding walks in an N-by-N lattice '''

    try:
        lattice_size = int(sys.argv[1])
        trials = int(sys.argv[2])
    except IndexError:
        print 'Integers for lattice size and trials are required.'
        print 'Syntax: "python selfavoidingwalk.py 20 1000'
        sys.exit(0)

    dead_ends = 0
    for _ in range(0, trials):
        grid = [[False for _ in range(lattice_size)]
                for _ in range(lattice_size)]
        point_x = lattice_size / 2
        point_y = lattice_size / 2

        while point_x > 0 and point_x < lattice_size-1 and \
              point_y > 0 and point_y < lattice_size-1:
            # Check for dead end and make a random move
            grid[point_x][point_y] = True
            if grid[point_x-1][point_y] and grid[point_x+1][point_y] and \
               grid[point_x][point_y-1] and grid[point_x][point_y+1]:
                dead_ends += 1
                break
            randval = random.random()
            if randval < .25:
                if not grid[point_x+1][point_y]:
                    point_x += 1
            elif randval < .50:
                if not grid[point_x-1][point_y]:
                    point_x -= 1
            elif randval < .75:
                if not grid[point_x][point_y+1]:
                    point_y += 1
            elif randval < 1.00:
                if not grid[point_x][point_y-1]:
                    point_y -= 1

    print str(100 * dead_ends/trials) + '% dead ends'


if __name__ == '__main__':
    main()
